package com.zhong.learning.auto_paper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lin.learning.questionmanagement.service.QuestionService;
import com.our.learning.infrastructure.constant.ResponseStatusEnum;
import com.our.learning.infrastructure.po.Paper;
import com.our.learning.infrastructure.po.Question;
import com.our.learning.infrastructure.pojo.Response;
import com.zhong.learning.auto_paper.dto.AutoPaperDTO;
import com.zhong.learning.auto_paper.mapper.AutoPaperMapper;
import com.zhong.learning.auto_paper.service.AutoPaperService;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author zhong
 * @date 2023/6/18
 */
@Service
public class AutoPaperServiceImpl extends ServiceImpl<AutoPaperMapper, Paper> implements AutoPaperService {
    private final AutoPaperMapper autoPaperMapper;
    private final QuestionService questionService;
    public AutoPaperServiceImpl(AutoPaperMapper autoPaperMapper, QuestionService questionService) {
        this.autoPaperMapper = autoPaperMapper;
        this.questionService = questionService;
    }
    @Override
    public Response autoCompose(AutoPaperDTO autoPaperDto) {
        Integer difficulty = autoPaperDto.getDifficulty();
//        List<String> questionTypes = autoPaperDto.getQuestionTypes();
//        List<Integer> questionNums = autoPaperDto.getQuestionNums();
        List<String> questionTypes = new ArrayList<>();
        List<Integer> questionNums = new ArrayList<>();
        List<Question> questionList = new ArrayList<>();
        // 选取每个题型的题目
        for (int i = 0; i < questionTypes.size(); i++) {
            String type = questionTypes.get(i);
            List<Question> questions = getRandomQuestionsOfOneType(type, questionNums.get(i), difficulty);
            // 数量超出题库中的数量
            if (questions == null)
                return new Response(ResponseStatusEnum.BAD_REQUEST)
                        .setMsg("超出[" + type + "]题目种类的数量");
            questionList.addAll(questions);
        }
        // 组成试卷
        Paper paper = autoPaperDto.toAutoPaper();
        paper.setQuestionList(questionList);
        // TODO: 设置分值（平分）
        List<Integer> scores = new ArrayList<>();
        // 存入试卷
        save(paper);
        int paperId = paper.getId();
        // 存入试卷题目关系
//        List<PaperQuestion> paperQuestionList = new ArrayList<>();
//        for (int i = 0; i < questionList.size(); i++) {
//            PaperQuestion paperQuestion = new PaperQuestion();
//            paperQuestion.setPaperId(paperId);
//            paperQuestion.setQuestionId(questionList.get(i).getId());
//            paperQuestion.setScore(scores.get(i));
//            paperQuestion.setTitleNo(i + 1);
//            paperQuestionList.add(paperQuestion);
//        }
//        paperQuestionService.saveBatch(paperQuestionList);
        return new Response(ResponseStatusEnum.OK).addData("paperId", paperId);
    }

    public Response getPaperById(Integer id) {
        LambdaQueryWrapper<Paper> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Objects.nonNull(id), Paper::getId, id);
        Paper paper = autoPaperMapper.selectOne(lambdaQueryWrapper);
        if (paper == null) {
            return new Response(ResponseStatusEnum.BAD_REQUEST).setMsg("查询不到对应ID的试卷");
        }
        // 处理试卷中的题目
        if (!setPaperQuestions(paper)) {
            return new Response(ResponseStatusEnum.BAD_REQUEST).setMsg("查询不到对应ID的题目");
        }
        return new Response(ResponseStatusEnum.OK).addData("paper", paper);
    }

    public Response getAll() {
        List<Paper> papers = autoPaperMapper.selectList(new LambdaQueryWrapper<>());
        for (Paper paper : papers) {
            if (paper == null) {
                return new Response(ResponseStatusEnum.BAD_REQUEST).setMsg("查询不到对应ID的试卷");
            }
            if (!setPaperQuestions(paper)) {
                return new Response(ResponseStatusEnum.BAD_REQUEST).setMsg("查询不到对应ID的题目");
            }
        }
        return new Response(ResponseStatusEnum.OK).addData("papers", papers);
    }

    /**
     * 根据题型、题目数量和难易度随机获取题目
     * @param type 题型
     * @param questionNum 题目数量
     * @param difficulty 难易度
     * @return 返回匹配的题目列表
     */
    private List<Question> getRandomQuestionsOfOneType(String type, Integer questionNum, Integer difficulty) {
        // 获取符合难度的该题型和数量
        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Question::getType, type);
        // TODO: 难易度
//        List<Question> questions = questionMapper.selectList(lambdaQueryWrapper);
        List<Question> questions = questionService.getQuestionByTypeAndDifficultyLocal(type, difficulty);
        // 数量不足
        if (questionNum > questions.size()) {
            return null;
        }
        // 随机选择题目
        questions = getRandomList(questions, questionNum);
        // TODO: 包含所有知识点
        return questions;
    }

    /**
     * 从题目列表中随机选择题目
     * @param list 题目列表
     * @param num 需要的题目数量
     * @return 随机选题后的列表
     */
    private List<Question> getRandomList(List<Question> list, Integer num) {
        if (num < list.size()) return null;
        List<Question> randomList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < num; i++) {
            int randomInt = random.nextInt(list.size() - 1);
            Question question = list.remove(randomInt);
            randomList.add(question);
        }
        return randomList;
    }

    private boolean setPaperQuestions(Paper paper) {
//        LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(Objects.nonNull(paper.getId()), PaperQuestion::getPaperId, paper.getId())
//                .orderByAsc(true, PaperQuestion::getTitleNo);
//        List<PaperQuestion> list = paperQuestionService.list(wrapper);
//        List<Question> questions = new ArrayList<>();
//        List<Integer> scores = new ArrayList<>();
//        for (PaperQuestion paperQuestion : list) {
//            int questionId = paperQuestion.getQuestionId();
//            int score = paperQuestion.getScore();
//            Question question = questionService.getQuestionByIdLocal(questionId);
//            if (question == null) {
//                return false;
//            }
//            questions.add(question);
//            scores.add(score);
//        }
//        paper.setQuestionList(questions);
//        paper.setScores(scores);
//        return true;
        return true;
    }
}
